﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SQLTouch.Service.DataContracts;

namespace SQLTouch.Client.Metro.ViewModel.Explore
{
    public class ExploreVM : VMBase
    {
        public class QueryVM : VMBase
        {
            private readonly IFacade facade;
            private readonly QueryData model;
            private readonly RelayCommand edit;
            private readonly RelayCommand delete;

            public QueryVM(IFacade facade, QueryData model)
            {
                this.facade = facade;
                this.model = model;
                this.edit = new RelayCommand(DoEdit);
                this.delete = new RelayCommand(DoDelete);
            }

            public QueryData Model
            {
                get { return model; }
            }

            public RelayCommand Edit
            {
                get { return edit; }
            }

            public RelayCommand Delete
            {
                get { return delete; }
            } 

            private void DoEdit()
            {
                try
                {
                    facade.ShowEditQuery(model);
                }
                catch (Exception ex)
                {
                    facade.ShowUnexpectedError("Unable to edit the query.", ex);
                }
            }

            private void DoDelete()
            {
                try
                {
                    facade.ShowDeleteQuery(model);
                }
                catch (Exception ex)
                {
                    facade.ShowUnexpectedError("Unable to delete the query.", ex);
                }
            }
        }

        private readonly IFacade facade;
        private readonly DatabaseData database;
        private readonly ObservableCollection<QueryVM> queries;
        private QueryVM selectedQuery;
        private readonly RelayCommand addQuery;
        private readonly RelayCommand back;

        public ExploreVM(IFacade facade, DatabaseData database)
        {
            this.facade = facade;
            this.database = database;
            this.queries = new ObservableCollection<QueryVM>(facade.GetQueries().Where(p => p.DatabaseId == database.Id).Select(p => new QueryVM(facade, p)).ToList());
            this.addQuery = new RelayCommand(DoAdd);
            this.back = new RelayCommand(DoBack);

            facade.QueryAdded += query => { if (query.DatabaseId == database.Id) queries.Add(new QueryVM(facade, query)); };
            facade.QueryUpdated += query => queries.Replace(p => p.Model.Id == database.Id, new QueryVM(facade, query));
            facade.QueryDeleted += query => queries.Remove(p => p.Model.Id == database.Id);
        }

        public RelayCommand AddQuery
        {
            get { return addQuery; }
        }

        public RelayCommand Back
        {
            get { return back; }
        } 

        public ObservableCollection<QueryVM> Queries
        {
            get { return queries; }
        }

        public QueryVM SelectedQuery
        {
            get { return selectedQuery; }
            set 
            {
                if (selectedQuery != value)
                {
                    selectedQuery = value;
                    RaisePropertyChanged("SelectedQuery");
                }
            }
        }

        private void DoAdd()
        {
            try
            {
                facade.ShowAddQuery(database);
            }
            catch (Exception ex)
            {
                facade.ShowUnexpectedError("Unable to add a query.", ex);
            }
        }

        private void DoBack()
        {
            facade.GoToHome();
        }
    }
}
